package com.db.ionio.serialization;

import java.io.*;
import java.net.Socket;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Alexander Kotov (kotov.alex.22@gmail.com)
 */
public class SerializationClient {
    private final String hostName;
    private final int port;
    private final int elementsCount;

    public SerializationClient(String hostName, int port, int elementsCount) {
        this.hostName = hostName;
        this.port = port;
        this.elementsCount = elementsCount;
    }

    public void run() {
        for (Serializer<SensorData[]> serializer : getAllSirializers().values()) {
            long start = System.currentTimeMillis();
            try (
                    Socket socket = new Socket(hostName, port);
                    DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
                    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
                    PrintWriter writer = new PrintWriter(dataOutputStream, true)) {

                System.out.println(serializer.getType());
                writer.println(serializer.getType());
                writer.flush();

                System.out.println("Sending " + elementsCount + " elements...");

                SensorData[] sensorDataBatch = new SensorData[elementsCount];
                for (int i = 0; i < elementsCount; i++) {
                    sensorDataBatch[i] = SensorData.generate();
                }
                serializer.serialize(sensorDataBatch, dataOutputStream);
                dataOutputStream.flush();
                System.out.println("Objects sent. Wait for response...");
                String response = null;
                while ((response = reader.readLine()) == null);
                //response = reader.readLine();
                System.out.println(response);
                long time = System.currentTimeMillis() - start;
                System.out.println("Time : " + time + "ms");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    static Map<String, Serializer<SensorData[]>> getAllSirializers() {
        Serializer<SensorData[]> serializer0 = new JavaSerializer<>();
        Serializer<SensorData[]> serializer1 = new XmlSerializer();
        Serializer<SensorData[]> serializer2 = new JsonSerializer();
        Serializer<SensorData[]> serializer3 = new ProtobufSerializer();
        Map<String, Serializer<SensorData[]>> serializerMap = new HashMap<>();
        serializerMap.put(serializer0.getType(), serializer0);
        serializerMap.put(serializer1.getType(), serializer1);
        serializerMap.put(serializer2.getType(), serializer2);
        serializerMap.put(serializer3.getType(), serializer3);
        return Collections.unmodifiableMap(serializerMap);
    }
}
